package com.gzsxy.esjy.config.refresh;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @author xiaolong
 * @version 1.0
 * @description: 监听刷新事件
 * @date 2021/12/23 15:33
 */
@Component
@Slf4j
@ConditionalOnProperty(name = "spring.profiles.refresh.enabled",havingValue = "true")
public class RefreshPropertyListener implements ApplicationListener<RefreshEvent> {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Value("${spring.application.name}")
    private String applicationName;

    /**
     * 消息总线广播方式发送给所有的客户端
     */
    private final static String REFRESHURL ="/actuator/bus-refresh";

    /**
     * 全局刷新配置文件
     */
    private final static String GLOBAL ="global";



    @Async
    @Override
    public void onApplicationEvent(RefreshEvent event) {

        //服务名  获取服务名下所有的主机信息服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances(applicationName);
        instances.forEach(server ->{

            //主机名
            String host = server.getHost();
            //端口
            int port = server.getPort();
            //协议
            String scheme = server.getScheme();
            String url = null;
            if (scheme == null){
                url = "http://";
            }else {
                url = "https://";
            }
            //bus全局动态刷新
            if (GLOBAL.equals(event.getApplication())){
                url += (host+":"+port+REFRESHURL);
               //指定服务刷新配置
            } else {
                List<ServiceInstance> instances1 = discoveryClient.getInstances(event.getApplication());
                Optional<Integer> first = instances1.stream().map(ServiceInstance::getPort).findFirst();
                Integer port1 = first.get();
                url += (host+":"+port+REFRESHURL+"/"+event.getApplication()+":"+port1);
            }
            //发送请求
            try {
                restTemplate.postForObject(url,new HashMap<String,Object>(),String.class);
                log.info("刷新配置路径url【{}】",url);
            } catch (RestClientException e) {
                log.error(e.getMessage(),e);
            }

        });

    }






    @Bean
//    @LoadBalanced
    public RestTemplate restTemplate(){
        return getRestTemplate();
    }


    private RestTemplate getRestTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        //换上fastjson
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
        while (iterator.hasNext()){
            HttpMessageConverter<?> converter = iterator.next();
            //原有的String是ISO-8859-1编码 去掉
            if (converter instanceof StringHttpMessageConverter){
                iterator.remove();
            }
            //由于系统中默认有jackson 在转换json时自动会启用 但是我们不想使用它 可以直接移除
            if (converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter){
                iterator.remove();
            }

        }
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.DisableCircularReferenceDetect);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        messageConverters.add(fastJsonHttpMessageConverter);
        return restTemplate;
    }
}
